package com.example.blemulticondemo.utils;

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.util.Log;

import java.util.Arrays;

/**
 * @author linvisf
 * @date 2024/8/6.
 * description：
 */
public class Protocol {
    private static final byte Package_Header_1 = 0x55;
    private static final byte Package_Header_2 = (byte) 0xAA;
    private static byte PackageNumber = 0;
    private static final byte SourceUnit = 0x11;
    private static final byte DescUnit = 0x21;

    //公共参数
    public static byte[] getCommonParam(int len) {
        final byte[] mTX = new byte[len];
        int index = 0;
        mTX[index++] = Package_Header_1;
        mTX[index++] = Package_Header_2;
        //包长度
        mTX[index++] = (byte) ((len - 4) >> 8);
        mTX[index++] = (byte) (len - 4);
        //包类型
        mTX[index++] = 0x01;
        //包号
        mTX[index++] = PackageNumber++;
        //源单元
        mTX[index++] = SourceUnit;
        //目标单元
        mTX[index++] = DescUnit;
        return mTX;
    }

    //查询试剂卡状态
    public static void queryReagentStatus(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x00;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //扫描试剂卡条码
    public static void scanReagentBarCode(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x02;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //开始光电采集
    public static void getLightData(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x03;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //荧光开关
    public static void setLightSwitch(Context context, BluetoothDevice device, boolean on) {
        byte[] mTX = getCommonParam(13);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x04;

        //data区
        if (on) {
            mTX[index++] = 0x01;
        } else {
            mTX[index++] = 0x00;
        }

        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //加热开关
    public static void setHeadSwitch(Context context, BluetoothDevice device, boolean on) {
        byte[] mTX = getCommonParam(13);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x12;
        //CMD SUB ID
        mTX[index++] = 0x05;

        //data区
        if (on) {
            mTX[index++] = 0x01;
        } else {
            mTX[index++] = 0x00;
        }

        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //设置加热目标温度
    public static void setHead(Context context, BluetoothDevice device, int temp) {
        byte[] mTX = getCommonParam(14);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x12;
        //CMD SUB ID
        mTX[index++] = 0x06;

        //data区
        mTX[index++] = (byte) (temp >> 8);
        mTX[index++] = (byte) (temp);

        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //启动PC数据采集模式
    public static void setPCControlMode(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x07;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //查询仪器内温度
    public static void getMachineTemp(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x12;
        //CMD SUB ID
        mTX[index++] = 0x08;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    // 蜂鸣器
    public static void collectCompleteBeep(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x12;
        //CMD SUB ID
        mTX[index++] = 0x09;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    //风扇控制
    public static void setFanSwitch(Context context, BluetoothDevice device, boolean on) {
        byte[] mTX = getCommonParam(13);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x05;

        //data区
        if (on) {
            mTX[index++] = 0x01;
        } else {
            mTX[index++] = 0x00;
        }

        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 查询系统参数的用户配置
     */
    public static void getFirmVersion(Context context, BluetoothDevice device) {
        Log.i("as", "Protocol: getFirmVersion");

        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x00;
        //CMD SUB ID
        mTX[index++] = 0x00;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    public static void writeSN(Context context, BluetoothDevice device, String sn) {
        Log.i("as", "Protocol: writeSN");
        Log.i("as", "sn===:" + sn);
        char[] ch = sn.toCharArray();
        int length = ch.length;
        int len = 12 + length + 1;
        Log.i("as", "len===:" + len);
        byte[] mTX = getCommonParam(len);
        Log.i("as", "mTX.len===:" + mTX.length);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x01;
        //CMD SUB ID
        mTX[index++] = 0x03;
        //data区
        mTX[index++] = (byte) (length);
        index = 11;
        for (int i = 0; i < length; i++) {
            mTX[index++] = (byte)ch[i];
        }
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    public static void readSN(Context context, BluetoothDevice device) {
        Log.i("as", "Protocol: readSN");

        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x00;
        //CMD SUB ID
        mTX[index++] = 0x02;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }


    /**
     * 查询系统参数的用户配置
     */
    public static void getSystemConfig(Context context, BluetoothDevice device) {
        Log.i("as", "Protocol: getSystemConfig");

        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x00;
        //CMD SUB ID
        mTX[index++] = 0x01;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 写入系统参数的用户配置
     */
//    public static void setSystemConfig(Context context, BluetoothDevice device, SystemConfig config) {
//        int len = 30;
//        byte[] mTX = getCommonParam(len);
//
//        int index = 8;
//
//        //CMD ID
//        mTX[index++] = 0x01;
//        //CMD SUB ID
//        mTX[index++] = 0x00;
//        //data区
//        mTX[index++] = (byte) (config.getStartPosition() >> 8);
//        mTX[index++] = (byte) (config.getStartPosition());
//        mTX[index++] = (byte) (config.getRunTotal() >> 8);
//        mTX[index++] = (byte) (config.getRunTotal());
//        mTX[index++] = (byte) (config.getMaxAD());
//        mTX[index++] = (byte) (config.getScanTime());
//        mTX[index++] = (byte) (config.getTemp() >> 8);
//        mTX[index++] = (byte) (config.getTemp());
//        mTX[index++] = (byte) (config.getTempSwitch());
//        mTX[index++] = (byte) (config.getDebugSwitch());
//        for (int i = 0; i < 8; i++) {
//            mTX[index++] = 0x00;
//        }
//        //CRC16
//        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
//        mTX[index++] = (byte) (crc >> 8);
//        mTX[index++] = (byte) (crc);
//        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
//    }

    /**
     * 恢复系统参数为厂家配置
     */
    public static void resetSystemConfig(Context context, BluetoothDevice device) {
        int len = 12;

        byte[] mTX = getCommonParam(len);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x01;
        //CMD SUB ID
        mTX[index++] = 0x02;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 读取ID卡
     */
    public static void readIDCard(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(13);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x04;
        //data
        mTX[index++] = 0x00;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    // 开始下位机老化测试
    public static void startXiaWeiJiOldTest(Context context, BluetoothDevice device, int count) {
        int len = 14;

        byte[] mTX = getCommonParam(len);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x11;
        //CMD SUB ID
        mTX[index++] = 0x05;
        mTX[index++] = (byte) (count >> 8);
        mTX[index++] = (byte) (count);
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    public static void sendACK(Context context, BluetoothDevice device, byte cmd, byte cmdSub, byte pn, byte result) {
        int len = 13;
        final byte[] mTX = new byte[len];
        int index = 0;
        mTX[index++] = Package_Header_1;
        mTX[index++] = Package_Header_2;
        //包长度
        mTX[index++] = (byte) ((len - 4) >> 8);
        mTX[index++] = (byte) (len - 4);
        //包类型
        mTX[index++] = 0x02;
        //包号
        mTX[index++] = pn;
        //源单元
        mTX[index++] = SourceUnit;
        //目标单元
        mTX[index++] = DescUnit;
        //CMD ID
        mTX[index++] = cmd;
        //CMD SUB ID
        mTX[index++] = cmdSub;
        //data区
        mTX[index++] = result;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        BRUtil.sendData(context, device, mTX);
    }

    public static void queryBatteryStatus(Context context, BluetoothDevice device) {
        byte[] mTX = getCommonParam(12);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x00;
        //CMD SUB ID
        mTX[index++] = 0x03;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 发送升级数据
     *
     * @param fileData
     */
    public static void sendUpgradingData(Context context, BluetoothDevice device, byte[] fileData, int pkNumber) {
        Log.i("F400", "指令02 02长度：" + fileData.length + "; 包号 = " + pkNumber);
        int len = 12 + fileData.length + 2;///////
        byte[] mTX = getCommonParam(len);
        int index = 8;

        //CMD ID
        mTX[index++] = 0x02;
        //CMD SUB ID
        mTX[index++] = 0x02;
        //data
        mTX[index++] = (byte) (pkNumber >> 8);
        mTX[index++] = (byte) (pkNumber);
        for (int i = 0; i < fileData.length; i++) {
            mTX[index++] = fileData[i];
        }
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 发送新升级指令信息
     */
//    public static void sendUpgradingCMDInfo(Context context, BluetoothDevice device, Version version, int fileLen, int fileCrc16) {
//        int len = 22;
//        byte[] mTX = getCommonParam(len);
//        int index = 8;
//
//        //CMD ID
//        mTX[index++] = 0x02;
//        //CMD SUB ID
//        mTX[index++] = 0x01;
//        //data
//        String softWare = version.getFirmVersion();
//        softWare = softWare.replace("V", "");
//        String softWareArray[] = softWare.split(".");
//        if (softWareArray.length < 4) {
//            Log.i("as", "========softWareArray.length < 4：" + softWare);
//            // return;
//        }
//        mTX[index++] = version.getV1();//(byte) Integer.parseInt(softWareArray[0].trim());
//        mTX[index++] = version.getV2();//(byte) Integer.parseInt(softWareArray[1].trim());
//        mTX[index++] = version.getV3();//(byte) Integer.parseInt(softWareArray[2].trim());
//        mTX[index++] = version.getV4();//(byte) Integer.parseInt(softWareArray[3].trim());
//        mTX[index++] = (byte) (fileLen >> 24);
//        mTX[index++] = (byte) (fileLen >> 16);
//        mTX[index++] = (byte) (fileLen >> 8);
//        mTX[index++] = (byte) (fileLen);
//        mTX[index++] = (byte) (fileCrc16 >> 8);
//        mTX[index++] = (byte) (fileCrc16);
//        //CRC16
//        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
//        mTX[index++] = (byte) (crc >> 8);
//        mTX[index++] = (byte) (crc);
//        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
//    }

    /**
     * 查询目标板子信息
     */
    public static void getBoradInfo(Context context, BluetoothDevice device) {
        int len = 12;
        byte[] mTX = getCommonParam(len);
        int index = 8;

        //CMD ID
        mTX[index++] = 0x02;
        //CMD SUB ID
        mTX[index++] = 0x00;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }

    /**
     * 发送升级完成指令
     */
    public static void sendUpgradingComplete(Context context, BluetoothDevice device) {
        int len = 12;
        byte[] mTX = getCommonParam(len);
        int index = 8;
        //CMD ID
        mTX[index++] = 0x02;
        //CMD SUB ID
        mTX[index++] = 0x03;
        //CRC16
        int crc = CRC16.GetCRC16(Arrays.copyOfRange(mTX, 4, mTX.length - 2));
        mTX[index++] = (byte) (crc >> 8);
        mTX[index++] = (byte) (crc);
        SendTimer.getInstance().setSendTimeOutStart(() -> BRUtil.sendData(context, device, mTX));
    }
}
